﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Transactions;
using Lapkin.Models.DataModels;

namespace Lapkin.Models.Repositories
{
    public class CategoryRepository
    {
        private readonly MainContext _db;
        private readonly SqlRepository _sqlRepository;
        public CategoryRepository(MainContext db, SqlRepository sqlRepository)
        {
            _sqlRepository = sqlRepository;
            _db = db;
        }

        public Category CreateCategory(Action<Category> init, Guid? parentId)
        {
            var createCategory = new Category
                {
                    Id = Guid.NewGuid(),
                };
            init(createCategory);
            var parentCategory = parentId != null ? new Category{Id = (Guid) parentId} : null;
            if (parentCategory != null)
            {
                _db.Categories.Attach(parentCategory);
            }
            try
            {
                createCategory.Parent = parentCategory;
                _db.Categories.Add(createCategory);
                _db.SaveChanges();
                return createCategory;
            }
            catch
            {
                return null;
            }

        }

        public bool UpdateCategory(Category category)
        {
            if (category.Id != Guid.Empty)
            {
                _db.Categories.Attach(category);
                _sqlRepository.CheckChange(category);
                _db.Configuration.ValidateOnSaveEnabled = false;
                _db.SaveChanges();
                _db.Configuration.ValidateOnSaveEnabled = true;
                return true;
            }
            return false;
        }

        public bool RemoveCategory(Guid id)
        {
            var category = new Category { Id = id };
            _db.Categories.Attach(category);
            _db.Categories.Remove(category);
            var products =
                        from p in _db.Products
                        where p.MainCategory == id
                        select p;
            foreach (var product in products)
            {
                //_db.Products.Remove(product);
                product.MainCategory = null;
            }
            try
            {
                _db.SaveChanges();
                return true;
            }
            catch
            {
                return false;
            }
        }

        public Category GetCategory(Expression<Func<Category, bool>> query)
        {
            return _db.Categories.FirstOrDefault(query);
        }

        public IEnumerable<Category> GetListCategory()
        {
            return _db.Categories.ToList();
        }

        public bool MoveCategory(Guid id, Guid? destination)
        {
            bool resultStatus = true;
            var currentCat = _db.Categories.FirstOrDefault(c => c.Id == id);
            var destinationCat = destination != null ? new Category {Id = (Guid) destination} : null;

            if (destinationCat != null)
            {
                _db.Categories.Attach(destinationCat);
            }

            if (currentCat == null)
            {
                resultStatus = false;
            }
            else
            {
                _db.Entry(currentCat).Reference(c => c.Parent).CurrentValue = destinationCat;
                try
                {
                    _db.SaveChanges();
                }
                catch
                {
                    resultStatus = false;
                }
            }
            
            return resultStatus;
        }
    }
}